using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input.Touch;
using Rocuna.GameEngine.Extension.WP7.Input.Constants;
using Rocuna.GameEngine.Input;

namespace Rocuna.GameEngine.Extension.WP7.Input
{
    /// <summary>
    /// Phone device to handle Gesture input.
    /// </summary>
    public class PhoneGestureDevice : BaseInputDevice
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="PhoneGestureDevice"/> class.
        /// </summary>
        /// <param name="game">Game that the game component should be attached to.</param>
        public PhoneGestureDevice(Game game)
            : base(game)
        {
            TouchPanel.EnabledGestures = GestureType.None;
            _actionMapping = new Dictionary<GestureType, List<Action<object>>>();
        }

        #region fields

        private Dictionary<GestureType, List<Action<object>>> _actionMapping;

        #endregion

        #region Implementation of IInputDevice

        /// <summary>
        /// Gets the name of the device.
        /// </summary>
        /// <value>
        /// The name of the device.
        /// </value>
        public override string DeviceName
        {
            get { return PhoneDevices.PhoneGestureDevice; }
        }

        /// <summary>
        /// Polls this device for input status.
        /// </summary>
        public override void Poll()
        {
            while (TouchPanel.IsGestureAvailable)
            {
                GestureSample gestureSample = TouchPanel.ReadGesture();
                if (_actionMapping.ContainsKey(gestureSample.GestureType))
                    foreach (var action in _actionMapping[gestureSample.GestureType])
                    {
                        action(gestureSample);
                    }
            }
        }

        /// <summary>
        /// Registers action to specified event.
        /// </summary>
        /// <param name="eventType">Type of the event.</param>
        /// <param name="action">The action.</param>
        public override void RegisterAction(object eventType, Action<object> action)
        {
            if (!(eventType is GestureType))
                return;
            var key = (GestureType)eventType;
            if (!(_actionMapping.ContainsKey(key)))
            {
                TouchPanel.EnabledGestures |= key;
                _actionMapping.Add(key, new List<Action<object>>());
            }
            _actionMapping[key].Add(action);
        }

        /// <summary>
        /// UnRegister action to specified event.
        /// </summary>
        /// <param name="eventType">Type of the event.</param>
        public override void UnRegisterAction(object eventType)
        {
            TouchPanel.EnabledGestures -= (GestureType)eventType;
            _actionMapping.Remove((GestureType)eventType);
        }

        #endregion

        /// <summary>
        /// Clears this instance.
        /// </summary>
        public void Clear()
        {
            TouchPanel.EnabledGestures = GestureType.None;
            _actionMapping.Clear();
        }
    }
}